/*
    Copyright 2006 Andrew Wilkinson <andrew@indiegigs.co.uk>

    This file is part of libgp2x.

    libgp2x is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    libgp2x is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with libgp2x; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <stdio.h>

#include "gp2x_internal.h"
#include "gp2x_stdlib.h"

FILE* stdout = (FILE*)0;
FILE* stderr = (FILE*)1;

FILE* fopen(const char* path, const char* mode) {
    FILE* fp;
    GP2x_fopen_info* info = malloc(sizeof(GP2x_fopen_info));
    info->path = path;
    info->mode = mode;
    fp = (FILE*)GP2x_postMessage(GP2x_MESSAGE_FOPEN, (unsigned long)GP2x_convert_ptr_to(info), 1);
    free(info);
    // We don't need to call GP2x_convert_ptr_from on fp as we'll never try to access it.
    return fp;
}

int fclose(FILE *fp) {
    GP2x_postMessage(GP2x_MESSAGE_FCLOSE, (unsigned long)fp, 0);
    return 0;
}

int fseek(FILE* stream, long offset, int whence) {
    int r;
    GP2x_fseek_info* info = malloc(sizeof(GP2x_fseek_info));
    info->stream = stream;
    info->offset = offset;
    info->whence = whence;
    r = GP2x_postMessage(GP2x_MESSAGE_FSEEK, (unsigned long)GP2x_convert_ptr_to(info), 1);
    free(info);
    return r;
}

long ftell(FILE* stream) {
    return GP2x_postMessage(GP2x_MESSAGE_FTELL, (unsigned long)stream, 1);
}

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) {
    size_t r;
    GP2x_frw_info* info = malloc(sizeof(GP2x_frw_info));
    info->stream = stream;
    info->size = size;
    info->nmemb = nmemb;
    info->ptr = GP2x_convert_ptr_to(ptr);
    r = (size_t)GP2x_postMessage(GP2x_MESSAGE_FREAD, (unsigned long)GP2x_convert_ptr_to(info), 1);
    free(info);
    return r;
}

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
    size_t r;
    GP2x_frw_info* info = malloc(sizeof(GP2x_frw_info));
    info->stream = stream;
    info->size = size;
    info->nmemb = nmemb;
    info->ptr = (void*)GP2x_convert_ptr_to(ptr);
    r = (size_t)GP2x_postMessage(GP2x_MESSAGE_FWRITE, (unsigned long)GP2x_convert_ptr_to(info), 1);
    free(info);
    return r;
}
